/**
 * 
 */
package fr.lelouet.ga.examples.travelingSalesman;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * A list of points to reach, plus the map of the world in which the travel
 * takes place.
 * 
 * @author le louet
 */
public class Travel extends ArrayList<Integer> implements Cloneable {

    private static final long serialVersionUID = 1L;

    protected WorldMap map;

    public WorldMap getMap() {
	return map;
    }

    public Travel(final WorldMap wm) {
	map = wm;
    }

    public Travel(final WorldMap wm, Integer[] firstTowns) {
	this(wm);
	addAll(Arrays.asList(firstTowns));
    }

    public float length() {
	if (this.size() == 0) {
	    return 0;
	}
	float ret = 0;
	Integer last = null;
	for (final Integer dest : this) {
	    if (last != null) {
		ret += map.length(last, dest);
		if (Float.isInfinite(ret)) {
		    return ret;
		}
	    }
	    last = dest;
	}
	return ret;
    }

    @Override
    public boolean equals(Object o) {
	if (o instanceof Travel) {
	    Travel t = (Travel) o;
	    if (t.map != map) {
		return false;
	    }
	    return super.equals(t);
	}
	return false;
    }

    /**
     * 
     * @return a list of the towns that have neigbourg but are no in this one
     *         travel.
     */
    public Set<Integer> missingTowns() {
	Set<Integer> ret = new HashSet<Integer>();
	ret.addAll(map.sociableTowns());
	for (Integer i : this) {
	    ret.remove(i);
	}
	return ret;
    }
}
